<!-- 上传图片 -->
<template>
  <el-upload
    ref="upload"
    v-model:file-list="fileList"
    :auto-upload="false"
    :limit="props.limit"
    :on-preview="handlePictureCardPreview"
    :on-remove="handleRemove"
    accept="image/*"
    list-type="picture-card"
  >
    <el-icon class="avatar-uploader-icon">
      <Plus />
    </el-icon>
  </el-upload>
  <el-button
    :disabled="subFlag"
    style="margin: 5px"
    type="primary"
    @click="handleSubmit"
    >上传
  </el-button>
  <el-image-viewer
    v-if="viewVisible"
    :initialIndex="initialIndex"
    :url-list="viewUrlList"
    :zoom-rate="1.2"
    preview-teleported
    @close="closePreview"
  />
</template>
<script lang="ts" setup>
import {
  defineEmits,
  defineProps,
  onMounted,
  onUnmounted,
  ref,
  watch,
} from "vue";
import type { UploadProps } from "element-plus";
import {
  ElLoading,
  ElMessage,
  UploadInstance,
  UploadUserFile,
} from "element-plus";
import { Plus } from "@element-plus/icons-vue";
import { ALiControllerService } from "@/api";

const emit = defineEmits(["update:url", "get:url"]);
const props = defineProps({
  // 图片限制
  limit: { type: Number, default: 1 },
  showUrl: { type: Boolean, default: false },
  urls: {
    type: Array,
    default: () => [],
  },
  //默认索引
  index: {
    type: Number,
    default: 0,
  },
});
//图片墙列表
const fileList = ref<UploadUserFile[]>([]);
const urlList = ref<string[]>([]);
if (props.urls?.length > 0) {
  //过滤出非空的字符,获取已上传的列表
  urlList.value = [...(props.urls as string[])].filter(
    (item) => item.trim().length > 0
  );
  if (urlList.value.length > 0) {
    //初始化照片墙数据
    fileList.value = urlList.value.map((item) => {
      return {
        url: item,
        name: item.substring(item.lastIndexOf("/") + 1),
      };
    });
  }
}
const upload = ref<UploadInstance>();

const dom = ref();
onMounted(() => {
  // 获取图片上传的dom元素列表
  let e = document.getElementsByClassName("el-upload el-upload--picture-card");
  if (e) {
    // 正常情况下，只有一个
    dom.value = e[props.index];
    fileList.value = [...fileList.value];
  }
});
const subFlag = ref(false);
//监听上传的文件列表
watch(
  () => fileList.value,
  () => {
    //判断是否有上传的文件
    subFlag.value =
      fileList.value.findIndex((item) => item.status === "ready") == -1;
    if (!dom.value) {
      return;
    }
    if (fileList.value.length >= props.limit) {
      //超过限制，隐藏上传
      dom.value.classList.add("upload-show");
      console.log("dom:", dom);
    } else {
      //不超过限制，正常显示
      dom.value.classList.remove("upload-show");
    }

    if (props.showUrl) {
      emit(
        "get:url",
        fileList.value.map((item) => item.url)
      );
    }
  },
  { deep: true }
);
// 预览的图片路径集合
const viewUrlList = ref<string[]>([]);
//预览初始索引
const initialIndex = ref<number>(0);
const viewVisible = ref(false); //预览弹窗标识
//关闭预览弹窗
function closePreview() {
  viewVisible.value = false;
}

const timeout = ref();
//移除事件
const handleRemove: UploadProps["onRemove"] = (uploadFile) => {
  console.log("触发移除");
  //移除了上传成功的图片
  if (uploadFile.status === "success") {
    // 找到索引
    let index = urlList.value.findIndex((url) => url === uploadFile.url);
    //移除文件
    urlList.value.splice(index, 1);
    //向父组件更新
    emit("update:url", urlList.value);
  }
};
//预览事件
const handlePictureCardPreview: UploadProps["onPreview"] = (uploadFile) => {
  viewUrlList.value = fileList.value.map((file) => file.url!);
  initialIndex.value = fileList.value.findIndex(
    (file) => file.url === uploadFile.url
  );
  viewVisible.value = true;
};
//提交事件
const sendCount = ref(0);
const uploadSize = ref(0);
const handleSubmit = () => {
  if (fileList.value.length == 0) {
    ElMessage.warning("请选择文件后再上传！");
    return;
  }
  const loading = ElLoading.service({
    lock: true,
    text: "上传中...",
    background: "rgba(0, 0, 0, 0.7)",
  });

  //过滤出需要上传的文件
  let uploadFiles = fileList.value.filter((item) => item.status === "ready");
  if (uploadFiles.length === 0) return;
  subFlag.value = true;
  sendCount.value = 0;
  uploadSize.value = uploadFiles.length;
  // 逐个上传
  for (let index = 0; index < uploadFiles.length; index++) {
    const item = uploadFiles[index];
    //类型及大小校验
    if (!item.raw?.type.startsWith("image/")) {
      ElMessage.warning(`第${index + 1}张需要上传的文件类型必须是图片类型!`);
      return;
    } else if (item.raw.size / 1024 / 1024 > 2) {
      ElMessage.error(`第${index + 1}张图片大小不能超过2MB!`);
      return;
    }
    timeout.value = setTimeout(() => {
      // 上传
      ALiControllerService.uploadImageUsingPost(
        undefined,
        item.raw as File
      ).then((res) => {
        sendCount.value = sendCount.value + 1;
        console.log(sendCount.value, index, uploadSize.value);
        if (sendCount.value === uploadSize.value) {
          loading.close();
        }
        let suc = fileList.value.findIndex(
          (file) => file.uid === item.uid && file.name === item.name
        );
        //设置为新url
        fileList.value[suc].url = res.data;
        //修改状态为上传成功！
        fileList.value[suc].status = "success";
        // 过滤出上传成功的图片
        let uploadFiles = fileList.value.filter(
          (item) => item.status === "success"
        );
        //获取图片路径
        urlList.value = uploadFiles.map((file) => file.url!);
        console.log("上传了", res.data);
        //向父组件更新
        emit("update:url", urlList.value);
      });
    }, 200);
    // uploadFiles.forEach((item, index) => {
    //   //类型及大小校验
    //   if (!item.raw?.type.startsWith("image/")) {
    //     ElMessage.warning(`第${index + 1}张需要上传的文件类型必须是图片类型!`);
    //     return;
    //   } else if (item.raw.size / 1024 / 1024 > 2) {
    //     ElMessage.error(`第${index + 1}张图片大小不能超过2MB!`);
    //     return;
    //   }
    //   // 上传
    //   ALiControllerService.uploadImageUsingPost(undefined, item.raw as File).then(
    //     (res) => {
    //       let suc = fileList.value.findIndex(
    //         (file) => file.uid === item.uid && file.name === item.name
    //       );
    //       //设置为新url
    //       fileList.value[suc].url = res.data;
    //       //修改状态为上传成功！
    //       fileList.value[suc].status = "success";
    //       // 过滤出上传成功的图片
    //       let uploadFiles = fileList.value.filter(
    //         (item) => item.status === "success"
    //       );
    //       //获取图片路径
    //       urlList.value = uploadFiles.map((file) => file.url!);
    //       console.log("上传了", res.data);
    //       //向父组件更新
    //       emit("update:url", urlList.value);
    //     }
    //   );
    // });
  }
};
onUnmounted(() => {
  if (timeout.value) {
    clearTimeout(timeout.value);
  }
});
</script>

<style lang="scss" scoped>
:deep(.avatar-uploader .el-upload) {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

:deep(.avatar-uploader .el-upload:hover) {
  border-color: var(--el-color-primary);
}

:deep(.el-icon.avatar-uploader-icon) {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}

:deep(.upload-show) {
  display: none !important;
}
</style>
